home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_ghostscript.idb / usr / freeware / lib / ghostscript / 3.33 / font2c.ps.z / font2c.ps
Encoding:
Text File  |  1998-05-21  |  17.6 KB  |  641 lines

  1. %    Copyright (C) 1992, 1993, 1994, 1995 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of GNU Ghostscript.
  3. % GNU Ghostscript is distributed in the hope that it will be useful, but
  4. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility to
  5. % anyone for the consequences of using it or for whether it serves any
  6. % particular purpose or works at all, unless he says so in writing.  Refer
  7. % to the GNU Ghostscript General Public License for full details.
  8.  
  9. % font2c.ps
  10. % Write out a PostScript Type 0 or Type 1 font as C code
  11. % that can be linked with the interpreter.
  12. % This even works on protected fonts, if you use the -dWRITESYSTEMDICT
  13. % switch in the command line.  The code is reentrant and location-
  14. % independent and has no external references, so it can be put into
  15. % a sharable library even on VMS.
  16.  
  17. % Define the maximum string length that all compilers will accept.
  18. % This must be approximately
  19. %    min(max line length, max string literal length) / 4 - 5.
  20.  
  21. /font2cdict 100 dict dup begin
  22.  
  23. /max_wcs 50 def
  24.  
  25. % Define a temporary file for writing out procedures.
  26. /wtempname (_.tmp) def
  27.  
  28. % ------ Protection utilities ------ %
  29.  
  30. % Protection values are represented by a mask:
  31. /a_noaccess 0 def
  32. /a_executeonly 1 def
  33. /a_readonly 3 def
  34. /a_all 7 def
  35. /prot_names
  36.  [ (0) (a_execute) null (a_readonly) null null null (a_all)
  37.  ] def
  38. /prot_opers
  39.  [ {noaccess} {executeonly} {} {readonly} {} {} {} {}
  40.  ] def
  41.  
  42. % Get the protection of an object.
  43.    /getpa
  44.     { dup wcheck
  45.        { pop a_all }
  46.        {    % Check for executeonly or noaccess objects in protected.
  47.          dup protected exch known
  48.       { protected exch get }
  49.       { pop a_readonly }
  50.      ifelse
  51.        }
  52.       ifelse
  53.     } bind def
  54.  
  55. % Get the protection appropriate for (all the) values in a dictionary.
  56.    /getva
  57.     { a_noaccess exch
  58.        { exch pop
  59.          dup type dup /stringtype eq 1 index /arraytype eq or
  60.      exch /packedarraytype eq or
  61.       { getpa a_readonly and or }
  62.       { pop pop a_all exit }
  63.      ifelse
  64.        }
  65.       forall
  66.     } bind def
  67.  
  68. % Keep track of executeonly and noaccess objects,
  69. % but don't let the protection actually take effect.
  70. .currentglobal
  71. false .setglobal    % so protected can reference local objs
  72. /protected        % do first so // will work
  73.   systemdict wcheck { 1500 dict } { 1 dict } ifelse
  74. def
  75. systemdict wcheck not
  76.  { (Warning: you will not be able to convert protected fonts.\n) print
  77.    (If you need to convert a protected font, please\n) print
  78.    (restart the program and specify the -dWRITESYSTEMDICT switch.\n) print
  79.    flush
  80.    (%end) .skipeof
  81.  }
  82. if
  83. userdict begin
  84.   /executeonly
  85.    { dup //protected exch //a_executeonly put readonly
  86.    } bind def
  87.   /noaccess
  88.    { dup //protected exch //a_noaccess put readonly
  89.    } bind def
  90. end
  91. true .setglobal
  92. systemdict begin
  93.   /executeonly
  94.    { userdict /executeonly get exec
  95.    } bind odef
  96.   /noaccess
  97.    { userdict /noaccess get exec
  98.    } bind odef
  99. end
  100. %end
  101. .setglobal
  102.  
  103. % ------ Output utilities ------ %
  104.  
  105. % By convention, the output file is named cfile.
  106.  
  107. % Define some utilities for writing the output file.
  108.    /wtstring 100 string def
  109.    /wb {cfile exch write} bind def
  110.    /ws {cfile exch writestring} bind def
  111.    /wl {ws (\n) ws} bind def
  112.    /wt {wtstring cvs ws} bind def
  113.  
  114. % Write a C string.  Some compilers have unreasonably small limits on
  115. % the length of a string literal or the length of a line, so every place
  116. % that uses wcs must either know that the string is short,
  117. % or be prepared to use wcca instead.
  118.    /wbx
  119.     { 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
  120.     } bind def
  121.    /wcst
  122.     [
  123.       32 { /wbx load } repeat
  124.       95 { /wb load } repeat
  125.       129 { /wbx load } repeat
  126.     ] def
  127.    ("\\) { wcst exch { (\\) ws wb } put } forall
  128.    /wcs
  129.     { (") ws { dup wcst exch get exec } forall (") ws
  130.     } bind def
  131.    /can_wcs    % Test if can use wcs
  132.     { length max_wcs le
  133.     } bind def
  134.    /wncs    % name -> C string
  135.     { wtstring cvs wcs
  136.     } bind def
  137. % Write a C string as an array of character values.
  138. % We only need this because of line and literal length limitations.
  139.    /wca        % string prefix suffix ->
  140.     { 0 4 -2 roll exch
  141.        { exch ws
  142.          exch dup 19 ge { () wl pop 0 } if 1 add
  143.      exch dup 32 ge 1 index 126 le and
  144.       { 39 wb dup 39 eq 1 index 92 eq or { 92 wb } if wb 39 wb }
  145.           { wt }
  146.          ifelse (,)
  147.        } forall
  148.       pop pop ws
  149.     } bind def
  150.    /wcca
  151.     { ({\n) (}) wca
  152.     } bind def
  153.  
  154. % Write object protection attributes.  Note that dictionaries are
  155. % the only objects that can be writable.
  156.    /wpa
  157.     { dup xcheck { (a_executable|) ws } if
  158.       dup type /dicttype eq { getpa } { getpa a_readonly and } ifelse
  159.       prot_names exch get ws
  160.     } bind def
  161.    /wva
  162.     { getva prot_names exch get ws
  163.     } bind def
  164.  
  165. % ------ Object writing ------ %
  166.  
  167.    /wnstring 128 string def
  168.  
  169. % Write a string/name or null as an element of a string/name/null array. */
  170.    /wsn
  171.     { dup null eq
  172.        { pop (\t255,255,) wl
  173.        }
  174.        { dup type /nametype eq { wnstring cvs } if
  175.          dup length 256 idiv wt (,) ws
  176.      dup length 256 mod wt
  177.      (,) (,\n) wca
  178.        }
  179.       ifelse
  180.     } bind def
  181. % Write a packed string/name/null array.
  182.    /wsna    % <name> <(string|name|null)*> wsna -
  183.     { (\tstatic const char ) ws exch wt ([] = {) wl
  184.       { wsn } forall
  185.       (\t0\n};) wl
  186.     } bind def
  187.  
  188. % Write a number or an array of numbers, as refs.
  189. /isnumber
  190.  { type dup /integertype eq exch /realtype eq or
  191.  } bind def
  192. /wnums
  193.  { dup isnumber
  194.     { (real_v\() ws wt (\),) ws }
  195.     { { wnums } forall }
  196.    ifelse
  197.  } bind def
  198.  
  199. % Test whether a procedure element can be written (printed).
  200. /iswx 4 dict dup begin
  201.   /arraytype { { iswproc } isall } def
  202.   /nametype { pop true } def
  203.   /operatortype { pop true } def    % assume it has been bound in
  204.   /packedarraytype /arraytype load def
  205. end def
  206. /iswnx 4 dict dup begin
  207.   /integertype { pop true } def
  208.   /nametype { pop true } def
  209.   /realtype { pop true } def
  210.   /stringtype { pop true } def
  211. end def
  212. /iswproc    % <obj> isproc <bool>
  213.  { dup xcheck { iswx } { iswnx } ifelse
  214.    1 index type .knownget { exec } { pop false } ifelse
  215.  } bind def
  216.  
  217. % Write a printable procedure (one for which iswproc returns true).
  218. /wproca 3 dict dup begin
  219.   /arraytype
  220.    { 1 index ({) writestring
  221.       { 1 index ( ) writestring 1 index exch wproc } forall
  222.      (}) writestring
  223.    } bind def
  224.   /packedarraytype /arraytype load def
  225.   /operatortype { .writecvs } bind def    % assume binding would work
  226. end def
  227. /wproc        % <file> <proc> wproc -
  228.  { dup type wproca exch .knownget { exec } { write==only } ifelse
  229.  } bind def
  230.  
  231. % Write a named object.  Return true if this was possible.
  232. % Legal types are: boolean, integer, name, real, string,
  233. % array of (integer, integer+real, name, null+string),
  234. % and certain procedures (see iswproc above).
  235. % All other objects are either handled specially or ignored.
  236.    /isall    % <array> <proc> isall <bool>
  237.     { true 3 -1 roll
  238.        { 2 index exec not { pop false exit } if }
  239.       forall exch pop
  240.     } bind def
  241.    /wott 8 dict dup begin
  242.       /arraytype
  243.        { woatt
  244.           { aload pop 2 index 2 index exec
  245.          { exch pop exec exit }
  246.          { pop pop }
  247.         ifelse
  248.       }
  249.      forall
  250.        } bind def
  251.       /booleantype
  252.        { { (\tmake_true\(&) } { (\tmake_false\(&) } ifelse ws
  253.          wt (\);) wl true
  254.        } bind def
  255.       /integertype
  256.        { (\tmake_int\(&) ws exch wt (, ) ws
  257.          wt (\);) wl true
  258.        } bind def
  259.       /nametype
  260.        { (\tcode = (*pprocs->name_create)\(&) ws exch wt
  261.          (, ) ws wnstring cvs wcs    % OK, names are short
  262.      (\);) wl
  263.      (\tif ( code < 0 ) return code;) wl
  264.      true
  265.        } bind def
  266.       /packedarraytype
  267.     /arraytype load def
  268.       /realtype
  269.        { (\tmake_real\(&) ws exch wt (, ) ws
  270.          wt (\);) wl true
  271.        } bind def
  272.       /stringtype
  273.        { ({\tstatic const char s_[] = ) ws
  274.          dup dup can_wcs { wcs } { wcca } ifelse
  275.      (;) wl
  276.      (\tmake_const_string\(&) ws exch wt
  277.      (, a_readonly, ) ws length wt (, (const byte *)s_\);) wl
  278.      (}) wl true
  279.        } bind def
  280.    end def
  281. % Write some other kind of object, if known.
  282.    /wother
  283.     { dup otherobjs exch known
  284.        { otherobjs exch get (\t) ws exch wt ( = ) ws wt (;) wl true }
  285.        { pop pop false }
  286.       ifelse
  287.     } bind def
  288. % Top-level procedure.
  289.    /wo        % name obj -> OK
  290.     { dup type wott exch .knownget { exec } { wother } ifelse
  291.     } bind def
  292.  
  293. % Write an array (called by wo).
  294.    /wap        % <name> <array> wap -
  295.     { dup xcheck not 1 index wcheck not and 1 index rcheck and
  296.        { pop pop }
  297.        { (\tr_set_attrs\(&) ws exch wt (, ) ws wpa (\);) wl }
  298.       ifelse
  299.     } bind def
  300.    /wnuma    % name array C_type type_v ->
  301.     { ({\tstatic const ref_\() ws exch ws
  302.       (\) a_[] = {) wl exch
  303.       dup length 0 eq
  304.        { (\t0) wl
  305.        }
  306.        { dup
  307.           { (\t) ws 2 index ws (\() ws wt (\),) wl
  308.       } forall
  309.        }
  310.       ifelse
  311.       (\t};) wl exch pop
  312.       (\tmake_const_array\(&) ws exch wt
  313.       (, avm_foreign|) ws dup wpa (, ) ws length wt
  314.       (, (const ref *)a_\);) wl
  315.       (}) wl
  316.     } bind def
  317.    /woatt [
  318.     % Integers
  319.      { { { type /integertype eq } isall }
  320.        { (long) (integer_v) wnuma true }
  321.      }
  322.     % Integers + reals
  323.      { { { type dup /integertype eq exch /realtype eq or } isall }
  324.        { (float) (real_v) wnuma true }
  325.      }
  326.     % Strings + nulls
  327.      { { { type dup /nulltype eq exch /stringtype eq or } isall }
  328.        { ({) ws dup (sa_) exch wsna
  329.      (\tcode = (*pprocs->string_array_create)\(&) ws exch wt
  330.      (, sa_, ) ws dup length wt (, ) ws wpa (\);) wl
  331.      (\tif ( code < 0 ) return code;) wl
  332.      (}) wl true
  333.        }
  334.      }
  335.     % Names
  336.      { { { type /nametype eq } isall }
  337.        { ({) ws dup (na_) exch wsna
  338.      (\tcode = (*pprocs->name_array_create)\(&) ws 1 index wt
  339.      (, na_, ) ws dup length wt (\);) wl
  340.      (\tif ( code < 0 ) return code;) wl
  341.      wap (}) wl true
  342.        }
  343.      }
  344.     % Procedure
  345.      { { iswproc }
  346.        {    % We'd like to use == and write directly to a string,
  347.         % but we can't do the former because of operators,
  348.         % and we can't do the latter because we can't predict
  349.         % how long the string would have to be....
  350.      wtempname (w) file 2 copy wproc closefile
  351.      wtempname status pop pop pop exch pop string
  352.      wtempname (r) file dup 3 -1 roll readstring pop exch closefile
  353.         % Stack: name proc string
  354.      ({\tstatic const char s_[] = ) ws
  355.          dup dup can_wcs { wcs } { wcca } ifelse
  356.      (;) wl
  357.      (\tcode = (*pprocs->ref_from_string)\(&) ws 2 index wt
  358.      (, s_, ) ws length wt (\);) wl
  359.      (\tif ( code < 0 ) return code;) wl
  360.      wap (}) wl true
  361.      wtempname deletefile
  362.        }
  363.      }
  364.     % Default
  365.      { { pop true }
  366.        { wother }
  367.      }
  368.    ] def
  369.  
  370. % Write a named dictionary.  We assume the ref is already declared.
  371.    /wd        % <name> <dict> <extra> wd -
  372.     { 3 1 roll
  373.       ({) ws
  374.       (\tref v_[) ws dup length wt (];) wl
  375.       dup [ exch
  376.        { counttomark 2 sub wtstring cvs
  377.          (v_[) exch concatstrings (]) concatstrings exch wo not
  378.           { (Skipping ) print ==only (....\n) print }
  379.      if
  380.        } forall
  381.       ]
  382.         % Stack: array of keys (names)
  383.       ({) ws dup (str_keys_) exch wsna
  384.       (\tstatic const cfont_dict_keys keys_ =) wl
  385.       (\t { 0, 0, ) ws length wt (, ) ws 3 -1 roll wt (, ) ws
  386.       dup wpa (, ) ws dup wva ( };) wl pop
  387.       (\tcode = \(*pprocs->ref_dict_create\)\(&) ws wt
  388.       (, &keys_, str_keys_, v_\);) wl
  389.       (\tif (code < 0) return code;) wl
  390.       (}) wl
  391.       (}) wl
  392.     } bind def
  393.  
  394. % Write character dictionary keys.
  395. % We save a lot of space by abbreviating keys which appear in
  396. % StandardEncoding or ISOLatin1Encoding.
  397. % Writes code to declare and initialize enc_keys_, str_keys, and keys_.
  398. /wcdkeys    % <dict> wcdkeys -
  399.  {    % Write keys present in StandardEncoding or ISOLatin1Encoding,
  400.     % pushing other keys on the o-stack.
  401.    (static const charindex enc_keys_[] = {) wl
  402.    dup [ exch 0 exch
  403.     { pop decoding 1 index known
  404.        { decoding exch get ({) ws dup -8 bitshift wt
  405.      (,) ws 255 and wt (}, ) ws
  406.      1 add dup 5 mod 0 eq { (\n) ws } if
  407.        }
  408.        { exch }
  409.       ifelse
  410.     }
  411.    forall pop
  412.    ]
  413.    ({0,0}\n};) wl
  414.     % Write other keys.
  415.    (str_keys_) exch wsna
  416.     % Write the declaration for keys_.
  417.    (static const cfont_dict_keys keys_ = {) wl
  418.    (\tenc_keys_, countof\(enc_keys_\) - 1,) wl
  419.    (\t) ws dup length wt ( - \(countof\(enc_keys_\) - 1\), 0, ) ws
  420.    dup wpa (, ) ws wva () wl
  421.    (};) wl
  422.  } bind def
  423.  
  424. % Enumerate character dictionary values in the same order that
  425. % the keys appear in enc_keys_ and str_keys_.
  426. % <proc> is called with each value in turn.
  427. /cdforall    % <dict> <proc> cdforall -
  428.  { 2 copy
  429.     { decoding 3 index known
  430.        { 3 -1 roll pop exec }
  431.        { pop pop pop }
  432.       ifelse
  433.     }
  434.    /exec cvx 3 packedarray cvx
  435.    /forall cvx
  436.    5 -2 roll
  437.     { decoding 3 index known
  438.        { pop pop pop }
  439.        { 3 -1 roll pop exec }
  440.       ifelse
  441.     }
  442.    /exec cvx 3 packedarray cvx
  443.    /forall cvx
  444.    6 packedarray cvx exec
  445.  } bind def
  446.  
  447. % ------ Writers for special objects ------ %
  448.  
  449. /writespecial 10 dict dup begin
  450.  
  451.    /FontInfo { 0 wd } def
  452.  
  453.    /Private { 0 wd } def
  454.  
  455.    /CharStrings
  456.     { ({) wl
  457.       dup wcdkeys
  458.       (static const char values_[] = {) wl
  459.        { wsn } cdforall
  460.       (\t0\n};) wl
  461.       (\tcode = \(*pprocs->string_dict_create\)\(&) ws wt
  462.       (, &keys_, str_keys_, values_\);) wl
  463.       (\tif ( code < 0 ) return code;) wl
  464.       (}) wl
  465.     } bind def
  466.  
  467.    /Metrics
  468.     { ({) wl
  469.       dup wcdkeys
  470.       (static const ref_(float) values_[] = {) wl
  471.       dup { (\t) ws wnums () wl } cdforall
  472.       (\t0\n};) wl
  473.       (static const char lengths_[] = {) wl
  474.        { (\t) ws dup isnumber
  475.       { pop 0 }
  476.       { length 1 add }
  477.      ifelse wt (,) wl
  478.        } cdforall
  479.       (\t0\n};) wl
  480.       (\tcode = \(*pprocs->num_dict_create\)\(&) ws wt
  481.       (, &keys_, str_keys_, (const ref *)values_, lengths_\);) wl
  482.       (\tif ( code < 0 ) return code;) wl
  483.       (}) wl
  484.     } bind def
  485.  
  486.    /Metrics2 /Metrics load def
  487.  
  488.    /FDepVector pop    % (converted to a list of font names)
  489.  
  490. end def
  491.  
  492. % ------ The main program ------ %
  493.  
  494. % Construct an inverse dictionary of encodings.
  495. [ /StandardEncoding /ISOLatin1Encoding
  496.   /SymbolEncoding /DingbatsEncoding
  497.   /KanjiSubEncoding
  498. ]
  499. dup length dict begin
  500.  { mark exch dup { .findencoding exch def } stopped cleartomark
  501.  } forall
  502. currentdict end /encodingnames exch def
  503.  
  504. % Invert the StandardEncoding and ISOLatin1Encoding vectors.
  505. 512 dict begin
  506.   0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } for
  507.   0 1 255 { dup StandardEncoding exch get exch def } for
  508. currentdict end /decoding exch def
  509.  
  510. /writefont        % cfilename procname -> [writes the current font]
  511.  { (gsf_) exch concatstrings
  512.      /fontprocname exch def
  513.    /cfname exch def
  514.    /cfile cfname (w) file def
  515.  
  516. % Remove unwanted keys from the font.
  517.    currentfont dup length dict begin { def } forall
  518.     { /FID /MIDVector /CurMID } { currentdict exch undef } forall
  519.    /Font currentdict end def
  520.  
  521. % Replace the FDepVector with a list of font names.
  522.    Font /FDepVector .knownget
  523.     { [ exch { /FontName get } forall ]
  524.       Font /FDepVector 3 -1 roll put
  525.     }
  526.    if
  527.  
  528. % Find all the special objects we know about.
  529. % wo uses this to write out references to otherwise intractable objects.
  530.    /otherobjs writespecial length dict dup begin
  531.      writespecial
  532.       { pop Font 1 index .knownget { exch def } { pop } ifelse
  533.       }
  534.      forall
  535.    end def
  536.  
  537. % Define a dummy FontInfo, in case the font doesn't have one.
  538.    /FontInfo 0 dict def
  539.  
  540. % Write out the boilerplate.
  541.    Font begin
  542.    (/* Portions of this file are subject to the following notice: */) wl
  543.    (/*) wl
  544.    ( * ) ws systemdict /copyright get wl
  545.    ( */) wl
  546.    FontInfo /Notice known
  547.     { (/* Portions of this file are also subject to the following notice: */) wl
  548.       (/****************************************************************) wl
  549.       FontInfo /Notice get wl
  550.       ( ****************************************************************/) wl
  551.     } if
  552.    () wl
  553.    (/* ) ws cfname ws ( */) wl
  554.    (/* This file was created by the ) ws product ws ( font2c utility. */) wl
  555.    () wl
  556.    (#include "ccfont.h") wl
  557.    () wl
  558.  
  559. % Write the procedure prologue.
  560.    (#ifdef __PROTOTYPES__) wl
  561.    (int huge) wl
  562.    fontprocname ws ((const cfont_procs *pprocs, ref *pfont)) wl
  563.    (#else) wl
  564.    (int huge) wl
  565.    fontprocname ws ((pprocs, pfont) const cfont_procs *pprocs; ref *pfont;) wl
  566.    (#endif) wl
  567.    ({\tint code;) wl
  568.    (\tref Font;) wl
  569.    otherobjs
  570.     { exch pop (\tref ) ws wt (;) wl }
  571.    forall
  572.  
  573. % Write out the special objects.
  574.    otherobjs
  575.     { exch writespecial 2 index get exec
  576.     }
  577.    forall
  578.  
  579. % Write out the main font dictionary.
  580. % If possible, substitute the encoding name for the encoding;
  581. % PostScript code will fix this up.
  582.     { /Encoding /PrefEnc }
  583.     { Font 1 index .knownget
  584.        { encodingnames exch .knownget { def } { pop } ifelse }
  585.        { pop }
  586.       ifelse
  587.     }
  588.    forall
  589.    (Font) Font FontType 0 eq { 5 } { 1 } ifelse wd
  590.  
  591. % Finish the procedural initialization code.
  592.    (\t*pfont = Font;) wl
  593.    (\treturn 0;) wl
  594.    (}) wl
  595.    end                % Font
  596.  
  597.    cfile closefile
  598.  
  599.  } bind def
  600.  
  601. end def            % font2cdict
  602.  
  603. % Compute the procedure name from the font name.
  604. /makefontprocname    % fontname -> procname
  605.  { =string cvs
  606.    dup length 1 sub -1 0
  607.     { dup =string exch get 45 eq { =string exch 95 put } { pop } ifelse
  608.     }
  609.    for 
  610.  } def
  611.  
  612. /writefont { font2cdict begin writefont end } def
  613.  
  614. % If the program was invoked from the command line, run it now.
  615. [ shellarguments
  616.  { counttomark dup 2 eq exch 3 eq or
  617.     { counttomark -1 roll cvn
  618.       (Converting ) print dup =only ( font.\n) print flush
  619.       dup FontDirectory exch known { dup FontDirectory exch undef } if
  620.       findfont setfont
  621.       (FontName is ) print currentfont /FontName get ==only (.\n) print flush
  622.       counttomark 1 eq
  623.        {    % Construct the procedure name from the file name.
  624.          currentfont /FontName get makefontprocname
  625.        }
  626.       if
  627.       writefont
  628.       (Done.\n) print flush
  629.     }
  630.     { cleartomark
  631.       (Usage: font2c fontname cfilename.c [shortname]\n) print
  632.       ( e.g.: font2c Courier cour.c\n) print flush
  633.       mark
  634.     }
  635.    ifelse
  636.  }
  637. if pop
  638.